//-----------------------------------------------------------------------------------
#include <QtGui>
#include <QTableWidget>
#include <QMessageBox>
#include <QFileDialog>
#include <QDir>
#include <QSqlRecord>
#include <QSqlField>
#include "CMyTable.h"
#include "CMyVariant.h"
//-----------------------------------------------------------------------------------
CMyTable::CMyTable(QWidget *parent) : QTableWidget(parent)
{
	colSort=-1;
	_ascending=Qt::AscendingOrder;
	_columnsModel=NULL;
	//setEditTriggers(QTableWidget::NoEditTriggers);
	hh=horizontalHeader();
	QObject::connect(hh, SIGNAL(sectionClicked(int)), this, SLOT(OnSectionClicked(int)));
	setSortingEnabled(false);
	setTextElideMode(Qt::ElideRight);
	setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
}
//-----------------------------------------------------------------------------------
void CMyTable::find(QString findText)
{
	int r=0;
	
	if(findText != "") 
	{
		if(_ascending == Qt::AscendingOrder)
		{
			r=quickFindASC(findText, 0, rowCount()-1);
		}else
		{
			r=quickFindDES(findText, 0, rowCount()-1);
		}
	}
	
	if(r != -1)
	{
		QModelIndex mi=indexAt(QPoint(0, 0));
		
		setCurrentCell(r, 0);
		scrollTo(mi.sibling(r, 0), QAbstractItemView::PositionAtTop);	
	}
}
//-----------------------------------------------------------------------------------
QString CMyTable::toCSV(QString separator, QString stringSeparator, QString lineEnd)
{	
	int x, y;
	QString ret="";
	QString s="";
	QString *sSeparator=new QString[columnCount()];
	
	for(x=0;x<columnCount();x++)
	{
		ret+=s+stringSeparator+model()->headerData(x, Qt::Horizontal).toString()+stringSeparator;
		s=separator;
	}
	
	ret+=lineEnd;
	for(y=0;y<rowCount();y++)
	{
		s="";
		for(x=0;x<columnCount();x++)
		{
			if(y == 0)
			{
				QVariant::Type typeColonne=QVariant::String;
			
				CMyTableWidgetItem *curItem=dynamic_cast<CMyTableWidgetItem *>(item(y, x));
				if(curItem != NULL)
				{
					typeColonne=curItem->getTypeColonne();
				}
				switch(typeColonne)
				{
					case QVariant::Double:
					case QVariant::Int: 	
					case QVariant::Bool: 	
					case QVariant::LongLong: 	
					case QVariant::UInt: 	
					case QVariant::ULongLong: 	
						sSeparator[x]="";
						break;
					default:
						sSeparator[x]=stringSeparator;
						break;
				}
			}
			
			ret+=s+sSeparator[x]+item(y, x)->text().replace(stringSeparator, stringSeparator+stringSeparator)+sSeparator[x];
			s=separator;
		}
		ret+=s+lineEnd;
	}
	
	delete[] sSeparator;
	return ret;
}
//-----------------------------------------------------------------------------------
void CMyTable::exportCSV(QString suggestFileName, QString separator, QString stringSeparator, QString lineEnd)
{
	QString fileName = QFileDialog::getSaveFileName(this, tr("Enregistrer sous"), QDir::toNativeSeparators(QDir::homePath()+"/")+suggestFileName, tr("Fichiers csv (*.csv)"));
	QFile *file;
	
	if(fileName != "")
	{
		file=new QFile(fileName);
		if(file->open(QIODevice::WriteOnly | QIODevice::Text))
		{
			QTextStream textStream(file);
			textStream.setCodec(QTextCodec::codecForName("utf8"));
			
			textStream << toCSV(separator, stringSeparator, lineEnd);
					
			delete file;
		}
	}
}
//-----------------------------------------------------------------------------------
void CMyTable::setColumnsModel(QList<CColumnModel *> *columnsModel) 
{
	QStringList header;
	
	_columnsModel=columnsModel;
	
	setColumnCount(_columnsModel->size());
	for(int i=0;i<_columnsModel->size(); i++)
	{
		header << _columnsModel->at(i)->getTitre();
	}
	
	setHorizontalHeaderLabels(header);
}
//-----------------------------------------------------------------------------------
int CMyTable::loadGrille(QSqlQuery *query, QString primaryKeyName) {
	int recAff=query->size();
	int Y=0;
	int X;
	
	setRowCount(recAff);
	setWordWrap(false);
	
	while(query->next()) {
		for(X=0;X<getColumnModelCount();X++) {
			CMyTableWidgetItem *item;
			CColumnModel *columnModel=getColumnModel(X);
			QSqlRecord rec=query->record();
			int champIdx=columnModel->getNumChamp();
			QSqlField field=rec.field(champIdx);
			int precision;
			
			if((precision = field.precision()) > 0) {
				columnModel->setData(QVariant(precision));
			}
			
			item=new CMyTableWidgetItem(columnModel->formatFromSQL(rec.value(champIdx).toString()), columnModel->getType());
			item->setTextAlignment(columnModel->getAlignment() | Qt::AlignVCenter);
			item->setIcon(*columnModel->getIcon());
			item->setFlags(columnModel->getFlags());
			
			if(!primaryKeyName.isEmpty() && X == 0) {
				item->setData(Qt::UserRole, rec.value(primaryKeyName));
			}
			
			emit beforeInsert(query, item);
			
			setItem(Y, X, item);
		}
		
		emit beforeChangeRecord(query, Y);
		Y++;
	}
	
	resizeRowsToContents();
	
	return Y;
}
//-----------------------------------------------------------------------------------
int CMyTable::quickFindASC(QString findText, int debut, int fin)
{
	int milieu;
	QString tableText;
	QVariant::Type type=QVariant::String;
	
	if(debut > fin) return -1;
	
	CMyTableWidgetItem *curItem=dynamic_cast<CMyTableWidgetItem *>(item(debut, colSort));
	if(curItem != NULL)
	{
		type=curItem->getTypeColonne();
	}
	
	CMyVariant valueToFind(findText, type);

	milieu=(debut+fin)/2;
	tableText=item(milieu, colSort)->text();
	
	CMyVariant tableValue(tableText, type);
	
	if(tableValue.compare(valueToFind) == 0)
	{
		while(milieu >= 0 && tableValue.compare(valueToFind) == 0)
		{
			milieu--;
			if(milieu >= 0)
			{
				tableText=item(milieu, colSort)->text();
				tableValue=CMyVariant(tableText, type);
			}
		}
			
		return milieu+1;
	}
	
	if(tableValue.compare(valueToFind) < 0)
	{
		return quickFindASC(findText, milieu+1, fin);
	}else
	{
		return quickFindASC(findText, debut, milieu-1);
	}
	
}
//-----------------------------------------------------------------------------------
int CMyTable::quickFindDES(QString findText, int debut, int fin)
{
	int milieu;
	QString tableText;
	QVariant::Type type=QVariant::String;
	
	if(debut > fin) return -1;
	
	CMyTableWidgetItem *curItem=dynamic_cast<CMyTableWidgetItem *>(item(debut, colSort));
	if(curItem != NULL)
	{
		type=curItem->getTypeColonne();
	}
	
	CMyVariant valueToFind(findText, type);
	
	milieu=(debut+fin)/2;
	tableText=item(milieu, colSort)->text();
	
	CMyVariant tableValue(tableText, type);
	
	if(tableValue.compare(valueToFind) == 0)
	{
		while(milieu >= 0 && tableValue.compare(valueToFind) == 0)
		{
			milieu--;
			if(milieu >= 0)
			{
				tableText=item(milieu, colSort)->text();
				tableValue=CMyVariant(tableText, type);
			}
		}
		return milieu+1;
	}
	
	if(tableValue.compare(valueToFind) > 0)
	{
		return quickFindDES(findText, milieu+1, fin);
	}else
	{
		return quickFindDES(findText, debut, milieu-1);
	}
	
}
//-----------------------------------------------------------------------------------
void CMyTable::keyPressEvent(QKeyEvent * e)
{
	switch(e->key())
	{
		case Qt::Key_Enter:
		case Qt::Key_Return:
			emit valid(currentRow(), currentColumn());
			break;
		case Qt::Key_Up:
		case Qt::Key_Down:
		case Qt::Key_PageUp:
		case Qt::Key_PageDown:
			QTableWidget::keyPressEvent(e);
			break;
		default:
			e->ignore();
			break;
	}
}
//-----------------------------------------------------------------------------------
void CMyTable::OnSectionClicked(int logicalIndex)
{
	if(isSortingEnabled())
	{
		if(logicalIndex != colSort)
		{
			colSort=logicalIndex;
			emit columnChange(logicalIndex);
			_ascending=Qt::AscendingOrder;
		}else
		{
			_ascending=(_ascending == Qt::AscendingOrder ? Qt::DescendingOrder : Qt::AscendingOrder);
		}
		sortByColumn(colSort, _ascending);
		emit ascendingChange(_ascending);
	}
}
//-----------------------------------------------------------------------------------
QString CMyTable::getValue(void) {
	return value;
}
//-----------------------------------------------------------------------------------
void CMyTable::setValue(QVariant value) {
	this->value=value.toString();
}
//-----------------------------------------------------------------------------------
void CMyTable::setStateEnable(bool enable) {
	if(_standaloneEnable) {
		setEnabled(enable);
	}
}
//-----------------------------------------------------------------------------------
void CMyTable::setAttribut(EAttribut value) {
}
//-----------------------------------------------------------------------------------
void CMyTable::setTextCondition(QString value) {
}
//-----------------------------------------------------------------------------------
bool CMyTable::isEmpty(void) {
	return value.isEmpty();
}
//-----------------------------------------------------------------------------------